package cn.tonyandmoney.warescanapp

import android.os.Bundle
import android.os.Process
import android.view.Gravity
import android.view.View
import android.widget.ProgressBar
import android.widget.TextView
import cn.tonyandmoney.warescanapp.common.WEB_SOCKET_URL
import cn.tonyandmoney.warescanapp.rfid.RFIdUtils
import cn.tonyandmoney.warescanapp.rfid.event.MiEvent
import cn.tonyandmoney.warescanapp.socket.RxConsumer
import cn.tonyandmoney.warescanapp.socket.RxSocketEvent
import cn.tonyandmoney.warescanapp.socket.RxWebSocketUtils
import cn.tonyandmoney.warescanapp.socket.dto.AppCheckDto
import com.dhh.rxlifecycle2.RxLifecycle
import com.google.gson.Gson
import com.zlzsy.app.base.ui.BaseActivity
import mpay.sdk.lib.interfaces.TimeoutListener
import org.jetbrains.anko.*

/**
 * 进来开启socket连接，
 * 有网页端控制，是否开始扫描
 */
class MainActivity : BaseActivity(), AnkoLogger, TimeoutListener {

    private val utils = RFIdUtils.utils
    private val commandLib = utils.commandLib
    private val mSocket = RxWebSocketUtils()

    private val mAppCheck = AppCheckDto(-1, "无操作", "", "")
    private lateinit var mStateText: TextView
    private lateinit var mProgressBar: ProgressBar
    private val mCheckListTag = mutableSetOf<String>()

    override fun initView() {
        frameLayout {
            textView {
                id = R.id.scan_state_text
                text = "开始扫描"
                padding = dip(10)
                backgroundResource = R.color.colorAccent
                mStateText = this
            }.lparams(wrapContent, wrapContent) {
                padding = dip(15)
            }
            progressBar {
                id = R.id.scan_progress_bar
                padding = dip(20)
                visibility = View.GONE
                mProgressBar = this
            }.lparams(wrapContent, wrapContent) {
                gravity = Gravity.CENTER
            }
        }
    }

    override fun initData(savedInstanceState: Bundle?) {
        utils.register<MiEvent>()
                .compose(RxLifecycle.with(this).bindOnDestroy())
                .subscribe(RxConsumer<MiEvent> { scanResult(it) })
        mSocket.register()
                .compose(RxLifecycle.with(this).bindOnDestroy())
                .subscribe(RxConsumer<RxSocketEvent> {
                    if (it.code == RxSocketEvent.CODE_MSG_STRING) {
                        onMessage(it.msg)
                    }
                })
        mSocket.connect(WEB_SOCKET_URL, this)

        commandLib.setCommandTimeoutListener(this)
        info("initData")
    }

    /**
     *  重置，取消所有的读取命令
     */
    private fun reset() {
        info("重置，取消清查命令")
        commandLib.cancelAllCommands()
        runOnUiThread {
            mStateText.text = "未开始扫描"
            mProgressBar.visibility = View.GONE
            mCheckListTag.clear()
            mAppCheck.reset()
        }

    }

    /**
     * 设置1s的超时时间，如果超时，就重新发送命令
     * 知道本次操作完成为止
     *
     *
     */
    private fun getActivate() {
        commandLib.cmdPICCActivate(5 * 60 * 1000)
        if (mProgressBar.visibility == View.GONE) {
            runOnUiThread {
                mProgressBar.visibility = View.VISIBLE
                mStateText.text = "正在扫描"
            }
        }
    }

    override fun onCommandTimeout(message: String?) {
        error("onCommandTimeout  -> $message")
    }

    private fun scanResult(result: MiEvent) {
        info("scanResult: $result")
        mAppCheck.epc = result.tag
        when (mAppCheck.code) {
            AppCheckDto.CODE_IN -> {
                mSocket.send(Gson().toJson(mAppCheck))
                reset()
            }
            AppCheckDto.CODE_CHECK, AppCheckDto.CODE_OUT -> {
                getActivate()
                if (mCheckListTag.contains(mAppCheck.epc)) {
                    return
                }
                mCheckListTag.add(mAppCheck.epc)
                mSocket.send(Gson().toJson(mAppCheck))
            }
        }
    }

    private fun onMessage(message: String) {
        info("onMessage: $message")
        val checkDto = Gson().fromJson(message, AppCheckDto::class.java) ?: return
        mAppCheck.fromDto(checkDto)
        when (checkDto.code) {
            AppCheckDto.CODE_IN, AppCheckDto.CODE_CHECK, AppCheckDto.CODE_OUT -> {
                getActivate()
            }
            AppCheckDto.CODE_SCAN_STOP -> {
                reset()
            }
        }
    }


    override fun onBackPressed() {
        if (mAppCheck.code == -1) {
            super.onBackPressed()
        } else {
            reset()
        }
    }

    override fun onDestroy() {
        commandLib.setBTListener(null)
        commandLib.setCommandTimeoutListener(null)
        commandLib.setCommandListener(null)
        commandLib.cancelAllCommands()
        commandLib.disconnectBTDevice()
        commandLib.btStop()
        super.onDestroy()
        Process.killProcess(Process.myPid())
    }

}
